package com.example.myapplication

import android.os.Environment
import android.util.Log
import com.example.myapplication.MainActivity.Companion.localIpAddress
import com.google.gson.Gson
import fi.iki.elonen.NanoHTTPD
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException
import java.net.URLDecoder
import java.nio.charset.Charset
import javax.security.auth.login.LoginException

class FileServer : NanoHTTPD(8080) {
    private val TAG = "lplplp"

    init {
        start(SOCKET_READ_TIMEOUT, true)
    }

    override fun serve(session: IHTTPSession): Response {
        val method = session.method
        val uri = session.uri

        if (Method.GET == method) {

            val uri = session.uri
            Log.e(TAG, "uri======" + uri)

            if (uri.startsWith("/delete")) {
                return delFile(session)
            } else {
                return handleGetRequest(uri)
            }

        } else if (Method.POST == method) {
            return handlePostRequest(session)
        }

        return newFixedLengthResponse(
            Response.Status.METHOD_NOT_ALLOWED,
            "text/plain",
            "Method not allowed"
        )
    }

    private fun delFile(session: IHTTPSession): Response {

        // 从请求参数中获取要删除的文件路径
        val query = session.parms["file"]
        Log.e(TAG, "query====" + query)

        if (query != null) {
            val file = File(query)
            if (file.exists()) {
                if (file.delete()) {
                    return newFixedLengthResponse(
                        Response.Status.OK,
                        "text/plain",
                        "File deleted successfully."
                    )
                } else {
                    return newFixedLengthResponse(
                        Response.Status.INTERNAL_ERROR,
                        "text/plain",
                        "Failed to delete file."
                    )
                }
            } else {
                return newFixedLengthResponse(
                    Response.Status.NOT_FOUND,
                    "text/plain",
                    "File not found."
                )
            }
        }
        return newFixedLengthResponse(Response.Status.BAD_REQUEST, "text/plain", "Invalid request.")
    }


    val ss = "\t<input type=\"file\" id=\"fileInput\"  name=\"uploadFile\"><br><br>\n" +
            "    <input type=\"submit\" value=\"提交\">\n" +
            "</form>\n" +
            "<script>\n" +
            "    const uploadForm = document.getElementById('uploadForm');\n" +
            "    const fileInput = document.getElementById('fileInput');\n" +
            "\n" +
            "    uploadForm.addEventListener('submit', function (e) {\n" +
            "      e.preventDefault();\n" +
            "      const file = fileInput.files[0];\n" +
            "      if (file) {\n" +
            "        const fileName = file.name;\n" +
            "        // 创建一个隐藏的input来传递文件名\n" +
            "        const hiddenInput = document.createElement('input');\n" +
            "        hiddenInput.type = 'hidden';\n" +
            "        hiddenInput.name = 'fileName';\n" +
            "        hiddenInput.value = fileName;\n" +
            "        uploadForm.appendChild(hiddenInput);\n" +
            "        // 发送表单数据\n" +
            "        const formData = new FormData(uploadForm);\n" +
            "        const xhr = new XMLHttpRequest();\n" +
            "        xhr.open('POST', '/upload', true);\n" +
            "\t\txhr.setRequestHeader(\"fn\",fileName)\n" +
            "        xhr.onload = function () {\n" +
            "          if (xhr.status === 200) {\n" +
            "            console.log('文件上传成功');\n" +
            "\t\t\t location.reload();\n" +
            "          } else {\n" +
            "            console.log('文件上传失败');\n" +
            "          }\n" +
            "        };\n" +
            "        xhr.send(formData);\n" +
            "      }\n" +
            "    });\n" +
            "</script>"

    private fun handleGetRequest(uri: String): Response {
        val filePath = ROOT_DIR + uri
        val file = File(filePath)

        if (file.exists()) {
            if (file.isDirectory) {
                val response = StringBuilder("<html>")
                response.append("<body>")

                response.append("<form  id=\"uploadForm\" action=\"").append(uri)
                    .append("\" method=\"post\" enctype=\"multipart/form-data\">")

                response.append(ss)
                response.append("</form><br>")

                val files = file.listFiles()
                if (files != null) {
                    for (f in files) {

                        var fp = f.absolutePath
                        val fileUri = if (uri.isEmpty() || uri == "/") {
                            "/" + f.name
                        } else {
                            uri + "/" + f.name
                        }


                        response.append("<a href=")
                            .append(fileUri)
                            .append("\">")
                            .append(f.name)
                            .append("</a>")


                        response.append(
                            """ <a> <button onclick="deleteFile()">删除</button><br>
    <script>
        function deleteFile() {
            if (confirm('是否确定删除该文件？')) {
                const encodedPath = encodeURIComponent('$fp');
                const url = 'http://$localIpAddress:$PORT/delete?file=' + encodedPath;
                fetch(url)
                   .then(response => response.text())
                   .then(data => {
                        // 无论删除结果如何，都刷新页面
                        location.reload();
                    })
                   .catch(error => alert('Error: ' + error));
            }
        }
    </script>
""".trimIndent()
                        )


                    }
                }


                response.append("</body></html>")
                return newFixedLengthResponse(Response.Status.OK, "text/html", response.toString())
            } else {
                if (file.canRead()) {
                    try {
                        val fis = FileInputStream(file)
                        val response = newFixedLengthResponse(
                            Response.Status.OK,
                            "application/octet-stream",
                            fis,
                            file.length().toInt().toLong()
                        )
                        response.addHeader(
                            "Content-Disposition",
                            "attachment; filename=\"" + file.name + "\""
                        )
                        return response
                    } catch (e: IOException) {
                        e.printStackTrace()
                        return newFixedLengthResponse(
                            Response.Status.INTERNAL_ERROR,
                            "text/plain",
                            "Error reading file"
                        )
                    }
                } else {
                    return newFixedLengthResponse(
                        Response.Status.FORBIDDEN,
                        "text/plain",
                        "No permission to read file"
                    )
                }
            }
        } else {
            return newFixedLengthResponse(Response.Status.NOT_FOUND, "text/plain", "File not found")
        }
    }

    private fun handlePostRequest(session: IHTTPSession): Response {

        try {

            Log.e(TAG, "handlePostRequest: headers " + Gson().toJson(session.headers))

            val headers = session.headers
            val contentType = headers["content-type"]
            if (contentType != null && contentType.startsWith("multipart/form-data")) {
                val files: Map<String, String> = HashMap()
                session.parseBody(files)



                for ((fieldName, tempFilePath) in files) {
                    if (tempFilePath.isNotEmpty()) {

                        val fileName = session.headers["fn"]
                        Log.e(TAG, "fileName===" + fileName)
                        val destFilePath = "/storage/emulated/0/$fileName"
                        val destFile = File(destFilePath)
                        FileInputStream(tempFilePath).use { `is` ->
                            FileOutputStream(destFile).use { fos ->
                                val buffer = ByteArray(1024)
                                var bytesRead: Int
                                while ((`is`.read(buffer).also { bytesRead = it }) != -1) {
                                    fos.write(buffer, 0, bytesRead)
                                }
                            }
                        }
                    }
                }

                return newFixedLengthResponse(
                    Response.Status.OK,
                    "text/plain",
                    "上传成功，请刷新地址"
                )
            }
            return newFixedLengthResponse(
                Response.Status.BAD_REQUEST,
                "text/plain",
                "Invalid request"
            )
        } catch (e: Exception) {
            e.printStackTrace()
            return newFixedLengthResponse(
                Response.Status.INTERNAL_ERROR,
                "text/plain",
                "Error uploading file"
            )
        }
    }


    companion object {
        private const val PORT = 8080
        private val ROOT_DIR: String = Environment.getExternalStorageDirectory().path
    }
}